package com.java3_18;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class java3_18 {
    //    public static void main(String[] args) {
//
//        //最多只能指定个数的线程执行，其他线程等待许可证
////        Semaphore semaphore = new Semaphore(3);
////        for (int i = 0; i < 6; i++) {
////            new Thread(() -> {
////                try {
////                    semaphore.acquire();
////                    System.out.println(Thread.currentThread().getName() + "正在使用线程");
////                    Thread.sleep(1000);
////                    System.out.println(Thread.currentThread().getName() + "----------结束使用线程");
////                    semaphore.release();
////                } catch (InterruptedException e) {
////                    throw new RuntimeException(e);
////                }
////            }, String.valueOf(i)).start();
////        }
//
////        ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
//
//
//    }
//    public static void main(String[] args) {
//        ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
//        ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock();
//        ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock();
//        HashMap<Integer, Integer> map = new HashMap<>();
//
//        //创建五个线程写入数据
//        for (int i = 1; i <= 5; i++) {
//            final int number = i;
//            new Thread(() -> {
//                writeLock.lock();
//                try {
//                    System.out.println(Thread.currentThread().getName() + "正在写入数据...");
//                    map.put(number, number);
//                    Thread.sleep(1000);
//                    System.out.println(Thread.currentThread().getName() + "-----写入完成");
//                } catch (InterruptedException e) {
//                    throw new RuntimeException(e);
//                } finally {
//                    writeLock.unlock();
//                }
//            }, String.valueOf(i)).start();
//        }
//
//        //创建五个线程读取数据
//        for (int i = 1; i <= 5; i++) {
//            final int number = i;
//            new Thread(() -> {
//                readLock.lock();
//                try {
//                    System.out.println(Thread.currentThread().getName() + "正在读取数据...");
//                    Integer i1 = map.get(number);
//                    Thread.sleep(1000);
//                    System.out.println(Thread.currentThread().getName() + ":  " +i1);
//                } catch (InterruptedException e) {
//                    throw new RuntimeException(e);
//                } finally {
//                    readLock.unlock();
//                }
//            }, String.valueOf(i)).start();
//        }
    //    public static void processData() {
//        ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); // 创建读写锁对象
//        int data = 0; // 共享数据
//        lock.writeLock().lock(); // 获取写锁
//        try {
//            // 执行数据处理操作
//            data++;
//            System.out.println("数据处理完成，当前值为: " + data);
//
//            // 锁降级：获取读锁
//            lock.readLock().lock();
//        } finally {
//            lock.writeLock().unlock(); // 释放写锁
//        }
//
//        try {
//            // 执行读操作
//            System.out.println("读取数据: " + data);
//        } finally {
//            lock.readLock().unlock(); // 释放读锁
//        }
//    }
//    public static void main(String[] args) {
//
//        ArrayBlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue<>(1);
//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                while (true) {
//                    try {
//                        arrayBlockingQueue.put("菜");
//                        System.out.println(Thread.currentThread().getName() + "做了一盘菜");
//                    } catch (InterruptedException e) {
//                        throw new RuntimeException(e);
//                    }
//                }
//            }
//        }, "厨师").start();
//
//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                while (true) {
//                    try {
//                        arrayBlockingQueue.take();
//                        System.out.println(Thread.currentThread().getName() + "吃了一盘菜");
//                    } catch (InterruptedException e) {
//                        throw new RuntimeException(e);
//                    }
//                }
//            }
//        }, "顾客").start();
//
//
//    }
    public static void main(String[] args) {
        //Semaphore的使用
        //给予通行证
//        Semaphore semaphore = new Semaphore(3);
//
//        for (int i = 1; i <= 10; i++) {
//            new Thread(()->{
//                try {
//                    //经过时判断是否还有通行证，如果没有了那么就阻塞
//                    semaphore.acquire();
//                    System.out.println(Thread.currentThread().getName()+"正在执行操作...");
//                    Thread.sleep(1000);
//                    System.out.println(Thread.currentThread().getName() + "执行完毕");
//                    semaphore.release();
//                } catch (InterruptedException e) {
//                    throw new RuntimeException(e);
//                }
//            },String.valueOf(i)).start();
//        }

        //读写锁
//        ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
//        HashMap<Object, Object> map = new HashMap<>();
//        CountDownLatch countDownLatch = new CountDownLatch(5);
//
//        for (int i = 1; i <= 5; i++) {
//            final int number = i;
//            new Thread(new Runnable() {
//                @Override
//                public void run() {
//                    try {
//                        //直到Latch变为0之后全部线程一同唤醒执行
//                        countDownLatch.await();
//                    } catch (InterruptedException e) {
//                        throw new RuntimeException(e);
//                    }
//                    reentrantReadWriteLock.readLock().lock();
//                    try {
//                        System.out.println(Thread.currentThread().getName() + "正在读取数据-------");
//                        Thread.sleep(1000);
//                        System.out.println(Thread.currentThread().getName() + ":   " + map.get(number));
//                    } catch (InterruptedException e) {
//                        throw new RuntimeException(e);
//                    } finally {
//                        reentrantReadWriteLock.readLock().unlock();
//                    }
//                }
//            }, String.valueOf(i)).start();
//        }
//
//        for (int i = 1; i <= 5; i++) {
//            final int number = i;
//            new Thread(new Runnable() {
//                @Override
//                public void run() {
//                    reentrantReadWriteLock.writeLock().lock();
//                    try {
//                        map.put(number, number);
//                        System.out.println(Thread.currentThread().getName() + "正在添加数据");
//                        Thread.sleep(1000);
//                        System.out.println(Thread.currentThread().getName() + "数据添加完毕");
//                        countDownLatch.countDown();
//                    } catch (InterruptedException e) {
//                        throw new RuntimeException(e);
//                    } finally {
//                        reentrantReadWriteLock.writeLock().unlock();
//                    }
//                }
//            }, String.valueOf(i)).start();
//        }

        //锁降级
//        ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
//        ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock();
//        ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock();
//        int number = 0;
//
//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                writeLock.lock();
//                try {
//                    System.out.println("开始输入数据...");
//                    Thread.sleep(1000);
//                    readLock.lock();
//                    System.out.println("开始读取数据...");
//                    writeLock.unlock();
//                } catch (InterruptedException e) {
//                    throw new RuntimeException(e);
//                }finally {
//                    readLock.unlock();
//                }
//            }
//        },"线程一").start();


        //BlockQueue
        //主要的两个实现类 -- ArrayBlockQueue 和 LinkedBlockQueue

        ArrayBlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue<>(4);


        //自动实现了阻塞和唤醒操作
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        System.out.println("厨师炒好了一盘菜");
                        Thread.sleep(1000);
                        arrayBlockingQueue.put("菜");
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        },"厨师1").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        System.out.println("厨师炒好了一盘菜");
                        Thread.sleep(1000);
                        arrayBlockingQueue.put("菜");
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        },"厨师2").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        System.out.println("厨师炒好了一盘菜");
                        Thread.sleep(1000);
                        arrayBlockingQueue.put("菜");
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        },"厨师3").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        System.out.println("厨师炒好了一盘菜");
                        Thread.sleep(1000);
                        arrayBlockingQueue.put("菜");
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        },"厨师4").start();

        new Thread(()->{
            while (true) {
                try {
                    System.out.println("客人吃了一盘菜---");
                    Thread.sleep(1000);
                    arrayBlockingQueue.take();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        },"客人1").start();
        new Thread(()->{
            while (true) {
                try {
                    System.out.println("客人吃了一盘菜---");
                    Thread.sleep(1000);
                    arrayBlockingQueue.take();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        },"客人2").start();



    }


}
